package com.daxue.configtest.utils;

import com.daxue.configtest.base.QueryConditions;
import com.daxue.configtest.exception.impl.BadArgumentException;
import cz.jirutka.rsql.parser.RSQLParser;
import cz.jirutka.rsql.parser.RSQLParserException;
import cz.jirutka.rsql.parser.ast.Node;
import cz.jirutka.rsql.parser.ast.RSQLVisitor;
import lombok.extern.slf4j.Slf4j;
import org.jooq.Condition;

import org.springframework.util.StringUtils;

import static com.daxue.configtest.base.QueryConditions.where;

/**
 * @author daxue0929
 * @date 2023/3/25
 */
@Slf4j
public class QueryParser {
    private static final RSQLParser PARSER = new RSQLParser();

    private static final RSQLVisitor<Condition, Void> VISITOR = new QueryVisitor();

    public static QueryConditions parse(Query query) throws BadArgumentException {
        return parse(query.gen());
    }

    public static QueryConditions parse(String queryStr) throws BadArgumentException {
        if (!StringUtils.hasText(queryStr)) {
            return where();
        }
        try {
            Node parseNode = PARSER.parse(queryStr);
            Condition condition = parseNode.accept(VISITOR);
            return where(condition);
        } catch (RSQLParserException e) {
            throw new BadArgumentException("Bad query syntax:" + queryStr, e);
        } catch (IllegalArgumentException e) {
            throw new BadArgumentException("Malformed query: " + queryStr, e);
        } catch (RuntimeException e) {
            throw new BadArgumentException("Bad query: " + queryStr, e);
        }
    }

}
